package controller

import (
	"bytes"
	"fmt"
	"fx_swift_agent/api"
	"fx_swift_agent/internal/service"
	"fx_swift_agent/pkg/code"
	"fx_swift_agent/pkg/global"
	"fx_swift_agent/pkg/internalerrors"
	"fx_swift_agent/pkg/logger"
	"fx_swift_agent/pkg/page"
	"fx_swift_agent/pkg/upload"
	"github.com/gin-gonic/gin"
	"github.com/golang-module/carbon/v2"
	"github.com/spf13/cast"
	"github.com/xuri/excelize/v2"
	"net/http"
)

func QueryAgentApply(c *gin.Context) {
	result, err := service.NewAgentSrv().QueryAgentApply(c)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, result)
	}
}

func UploadEnterpriseInfo(c *gin.Context) {
	req := &api.EnterpriseAccountApplyReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		code.Fail(c, http.StatusBadRequest, code.ErrEncodingJSON, err.Error())
		return
	}
	err := service.NewAgentSrv().UploadEnterpriseInfo(c, req)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, nil)
	}
}

func GetCountryInfo(c *gin.Context) {
	result, err := service.NewAgentSrv().GetCountryInfo(c)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, result)
	}
}

func GetCardCountryInfo(c *gin.Context) {
	result, err := service.NewAgentSrv().GetCardCountryInfo(c)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, result)
	}
}

func GetCompanyType(c *gin.Context) {
	result, err := service.NewAgentSrv().GetCompanyType(c)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, result)
	}
}

func SubmitDiscountOrder(c *gin.Context) {
	req := &api.SubmitDiscountOrderReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		code.Fail(c, http.StatusBadRequest, code.ErrEncodingJSON, err.Error())
		return
	}
	err := service.NewAgentSrv().SubmitDiscountOrder(c, req)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, nil)
	}
}

func CashFlowList(c *gin.Context) {
	req := &api.CashFlowListReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		code.Fail(c, http.StatusBadRequest, code.ErrEncodingJSON, err.Error())
		return
	}
	result, err := service.NewAgentSrv().CashFlowList(c, req)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, result)
	}
}

func OperatorAgentCallBack(c *gin.Context) {
	url := c.Query("url")
	err := service.NewAgentSrv().OperatorAgentCallBack(c, url)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, nil)
	}
}

func AgentCallBackInfo(c *gin.Context) {
	result, err := service.NewAgentSrv().AgentCallBackInfo(c)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	} else {
		code.Success(c, result)
	}
}

func ExportCashFlow(c *gin.Context) {
	var (
		err      error
		filePath string
		// 获取最大导出数
		maxNum  = global.ViperObj.GetInt("export.maxNum")
		account = c.GetString("Account")
		line    = 1
		result  *page.Collection[*api.CashFlowListRes]
	)
	logger.SugarLogger.Infof("开始时间为：%s", carbon.Now().ToDateTimeString())
	req := &api.CashFlowListReq{}
	if err = c.ShouldBindJSON(&req); err != nil {
		code.Fail(c, http.StatusBadRequest, code.ErrEncodingJSON, err.Error())
		return
	}
	req.PageSize = cast.ToUint64(maxNum)

	logger.SugarLogger.Infof("SQL查询开始时间为：%s", carbon.Now().ToDateTimeString())
	result, err = service.NewAgentSrv().CashFlowList(c, req)
	if err != nil {
		code.Fail(c, http.StatusBadRequest, err.(internalerrors.ServiceError).Code, err.(internalerrors.ServiceError).Msg)
		return
	}
	logger.SugarLogger.Infof("SQL查询结束时间为：%s", carbon.Now().ToDateTimeString())

	f := excelize.NewFile() // 设置单元格的值
	index, _ := f.NewSheet("Sheet1")
	// 这里设置表头
	f.SetCellValue("Sheet1", "A1", "流水号")
	f.SetCellValue("Sheet1", "B1", "交易时间")
	f.SetCellValue("Sheet1", "C1", "币种")
	f.SetCellValue("Sheet1", "D1", "金额")
	f.SetCellValue("Sheet1", "E1", "剩余金额")
	f.SetCellValue("Sheet1", "F1", "类型")
	f.SetCellValue("Sheet1", "G1", "状态")

	if len(result.List) > maxNum {
		code.Fail(c, http.StatusBadRequest, code.ErrCanNotOpenFile, "导出数据太多，请分批导出")
		return
	}
	// 循环写入数据
	for _, v := range result.List {
		line++
		f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), v.DiscountOrderNo)
		f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), v.CreatedAt)
		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), "USD")
		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.Amount)
		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.RemainingBalance)
		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.RecordDesc)
		if v.RecordType == "transfer" {
			f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), "转账扣款")
		} else if v.RecordType == "openCard" {
			f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), "开卡费扣款")
		} else if v.RecordType == "fee" {
			f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), "充值手续费扣款")
		} else if v.RecordType == "xqFee" {
			f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), "商家强制清算扣款")
		} else if v.RecordType == "refund" {
			f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), "退款成功")
		}
	}

	f.SetActiveSheet(index)

	var buffer bytes.Buffer
	_ = f.Write(&buffer)
	content := bytes.NewReader(buffer.Bytes())
	logger.SugarLogger.Infof("上传文件开始时间为：%s", carbon.Now().ToDateTimeString())
	fileName := fmt.Sprintf("download/%s%s%s.xlsx", account, `-`, "exportCashFlow")
	if filePath, err = upload.UploadToS3Srv(fileName, content); err != nil || len(filePath) == 0 {
		code.Fail(c, http.StatusBadRequest, code.ErrCanNotOpenFile, err.Error())
		return
	}
	logger.SugarLogger.Infof("上传文件结束时间为：%s", carbon.Now().ToDateTimeString())
	logger.SugarLogger.Infof("结束时间为：%s", carbon.Now().ToDateTimeString())
	code.Success(c, filePath)
}
